﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SCMS.CoreBusinessLogic.OrderRequest;
using SCMS.CoreBusinessLogic.Web;
using SCMS.Model;
using SCMS.UI.Models;
using System.Data.Objects.DataClasses;
using SCMS.UI.GeneralHelper;
using System.Text;
using SCMS.CoreBusinessLogic.ActionFilters;
using SCMS.CoreBusinessLogic.Security;
using SCMS.CoreBusinessLogic.NotificationsManager;
using SCMS.CoreBusinessLogic._Location;
using SCMS.CoreBusinessLogic._Item;
using SCMS.CoreBusinessLogic.ProcurementPlan;
using SCMS.CoreBusinessLogic._ExchangeRate;
using SCMS.CoreBusinessLogic._Currency;

namespace SCMS.UI.Controllers
{
    [MyException]
    public class OrderRequestController : PortalBaseController
    {
        private IOrderRequest orderRequestService;
        private UI.Models.ORequest OdersRequest;
        private List<UI.Models.LoadORDetailsz> ORItemsz;
        private INotificationService notificationService;
        private ILocationService locationService;
        private IItemService itemService;
        private IProcurementPlanService ppService;
        private IExchangeRateService exchangeRateService;
        private ICurrencyService currencyService;

        public OrderRequestController(IPermissionService permissionService, IOrderRequest orderRequestService, IUserContext userContext,
            INotificationService notificationService, ILocationService locationService, IItemService itemService, IProcurementPlanService ppService,
            IExchangeRateService exchangeRateService, ICurrencyService currencyService)
            : base(userContext, permissionService)
        {
            this.orderRequestService = orderRequestService;
            this.notificationService = notificationService;
            this.locationService = locationService;
            this.itemService = itemService;
            this.ppService = ppService;
            this.exchangeRateService = exchangeRateService;
            this.currencyService = currencyService;
        }

        //
        // GET: /OrderRequest/

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult LoadOrderRequest(bool fromPP = false)
        {
            List<Model.Project> projects = fromPP ? orderRequestService.GetProjectsWithPP(countryProg.Id) : orderRequestService.GetProject(countryProg.Id);
            using (var db = new SCMSEntities())
            {
                OdersRequest = new Models.ORequest()
                {
                    EntityOrderRequest = new Model.OrderRequest(),
                    currencies = new SelectList(orderRequestService.GetCurrencies(countryProg.Id), "Id", "ShortName"),
                    Projects = new SelectList(projects, "Id", "Name"),
                    ProjectNos = new SelectList(orderRequestService.GetProjectNos(countryProg.Id, Guid.Empty), "Id", "ProjectNumber"),
                    RequestDelivLocations = new SelectList(orderRequestService.GetLocations(countryProg.Id), "Id", "Name"),
                    FinalDelivLocations = new SelectList(orderRequestService.GetLocations(countryProg.Id), "Id", "Name"),
                    OrderRequestNo = "--NEW OR--", //this.GenerateUniqueCode(),
                    CurrencyID = countryProg.Country.CurrencyId.HasValue ? countryProg.Country.CurrencyId.Value : mbCurrency.Id,
                    FromPP = fromPP
                };

                return View(OdersRequest);
            }
        }

        public ActionResult EditOrderRequest(Guid id)
        {
            Model.OrderRequest or = orderRequestService.GetOrderRequestById(id);
            OdersRequest = new Models.ORequest()
                {
                    EntityOrderRequest = or,
                    currencies = new SelectList(orderRequestService.GetCurrencies(countryProg.Id), "Id", "ShortName", or.CurrencyId),
                    Projects = new SelectList(orderRequestService.GetProject(countryProg.Id), "Id", "Name", or.ProjectDonor.ProjectId),
                    ProjectNos = new SelectList(orderRequestService.GetProjectNos(countryProg.Id, or.ProjectDonor.ProjectId), "Id", "ProjectNumber", or.ProjectDonorId),
                    RequestDelivLocations = new SelectList(orderRequestService.GetLocations(countryProg.Id), "Id", "Name", or.RequestedDestinationId),
                    FinalDelivLocations = new SelectList(orderRequestService.GetLocations(countryProg.Id), "Id", "Name", or.FinalDestinationId),
                    OrderRequestNo = or.RefNumber,
                    IssueDate = or.OrderDate,
                    RequestDate = or.DeliveryDate,
                    CurrencyID = or.CurrencyId,
                    ProjectId = or.ProjectDonor.ProjectId,
                    ProjectDonorId = or.ProjectDonorId,
                    RequestDelivLocationID = (Guid)or.RequestedDestinationId,
                    FinalDelivLocationID = (Guid)or.FinalDestinationId
                };
            ViewBag.Donor = or.ProjectDonor.Donor.ShortName;
            return View(OdersRequest);
        }

        public ActionResult GetProjectNos(Guid id)
        {
            StringBuilder blineOption = new StringBuilder();
            blineOption.Append("<select data-val=\"true\" data-val-required=\"Required Field\" id=\"dplProNo\" name=\"ProjectDonorId\" onchange=\"javascript:GetDonor(this)\"><option value=\"\">---Please Select---</option>");
            List<Model.ProjectDonor> BLines = orderRequestService.GetProjectNos(countryProg.Id, id);
            foreach (ProjectDonor item in BLines)
                blineOption.Append("<option value=\"" + item.Id + "\">" + item.ProjectNumber + " (" + item.Donor.ShortName + ") " + "</option>");
            blineOption.Append("</select>");
            blineOption.Append("<span class=\"field-validation-valid\" data-valmsg-for=\"ProjectDonorId\" data-valmsg-replace=\"true\"></span>");
            ViewBag.Html = blineOption.ToString();
            return View("SelectIndexChangeResponse");
        }

        public ActionResult GetProjectNos4RegAsset(Guid id)
        {
            StringBuilder blineOption = new StringBuilder();
            blineOption.Append("<select data-val=\"true\" data-val-required=\"Required\" id=\"dplProNo\" name=\"EntityAsset.CurrentProjectDonorId\" onchange=\"javascript:GetAssetNo(this)\"><option value=\"\">---Please Select---</option>");
            List<Model.ProjectDonor> BLines = orderRequestService.GetProjectNos(countryProg.Id, id);
            foreach (ProjectDonor item in BLines)
                blineOption.Append("<option value=\"" + item.Id + "\">" + item.ProjectNumber + " (" + item.Donor.ShortName + ") " + "</option>");
            blineOption.Append("</select>");
            blineOption.Append("<span class=\"field-validation-valid\" data-valmsg-for=\"EntityAsset.CurrentProjectDonorId\" data-valmsg-replace=\"true\"></span>");
            ViewBag.Html = blineOption.ToString();
            return View("SelectIndexChangeResponse");
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult SaveOrderRequest(Models.ORequest entity)
        {
            entity.EntityOrderRequest = new Model.OrderRequest();
            entity.EntityOrderRequest.Id = Guid.NewGuid();
            entity.EntityOrderRequest.CountryProgrammeId = countryProg.Id;
            entity.EntityOrderRequest.PreparedBy = currentStaff.Id;
            entity.EntityOrderRequest.TotalAmount = 0;
            entity.EntityOrderRequest.IsReviewed = false;
            entity.EntityOrderRequest.IsAuthorized = false;
            entity.EntityOrderRequest.ProjectId = entity.ProjectId;
            entity.EntityOrderRequest.RefNumber = entity.OrderRequestNo;
            entity.EntityOrderRequest.CurrencyId = entity.CurrencyID;
            entity.EntityOrderRequest.ProjectDonorId = entity.ProjectDonorId;
            entity.EntityOrderRequest.RequestedDestinationId = entity.RequestDelivLocationID;
            entity.EntityOrderRequest.FinalDestinationId = entity.FinalDelivLocationID;
            entity.EntityOrderRequest.PreparedOn = DateTime.Now;
            entity.EntityOrderRequest.OrderDate = entity.IssueDate;
            entity.EntityOrderRequest.DeliveryDate = entity.RequestDate;
            //}

            UserSession.CurrentSession.NewOR = entity.EntityOrderRequest;
            if (entity.FromPP)
                return AddPPItems2OR(entity.ProjectDonorId.Value, entity.EntityOrderRequest);
            return PopulateCreateItem(entity.EntityOrderRequest.Id);
        }

        public ActionResult AddPPItems2OR(Guid pdId, Model.OrderRequest or)
        {
            List<ProcurementPlanItem> ppItems = ppService.GetPPItemsForOR(pdId);
            if (ppItems == null || ppItems.Count == 0)
            {
                return Content("<i style=\"color: Red\">There are currently no Procurment Plan Items for the selected project. CANNOT PROCEED</i>", "text/html");
            }
            PPModel model = new PPModel();
            model.OrderRequestId = or.Id;
            model.EntityPP = ppItems.Count > 0 ? ppService.GetProcurementPlanById(ppItems[0].ProcurementPlanId) : new ProcurementPlan();
            model.PPItems = new List<PPItemModel>();
            Currency orCurr = currencyService.GetCurrency(or.CurrencyId);
            foreach (ProcurementPlanItem ppItem in ppItems)
            {
                ppItem.UnitCost = Math.Round(exchangeRateService.GetForeignCurrencyValue(or.CurrencyId, ppItem.CurrencyId, ppItem.UnitCost, countryProg.Id), 2);
                ppItem.TotalCost = Math.Round((ppItem.UnitCost * ppItem.Quantity), 2);
                model.PPItems.Add(new PPItemModel { EntityPPItem = ppItem });
            }
            ViewBag.Currency = orCurr.ShortName;
            return View("AddPPItems2OR", model);
        }

        [HttpPost]
        public ActionResult AddPPItems2OR(PPModel model)
        {
            Model.OrderRequest or = UserSession.CurrentSession.NewOR != null ? UserSession.CurrentSession.NewOR : orderRequestService.GetOrderRequestById(model.OrderRequestId);
            Model.OrderRequestItem orItem;
            ProcurementPlanItem ppItem;
            foreach(PPItemModel ppItemModel in model.PPItems)
            {
                if (!ppItemModel.EntityPPItem.AddedToOR)
                    continue;
                ppItem = ppService.GetProcurementPlanItemById(ppItemModel.EntityPPItem.Id);
                orItem = new OrderRequestItem();
                orItem.BudgetLineId = ppItem.BudgetLineId;
                orItem.EstimatedUnitPrice = exchangeRateService.GetForeignCurrencyValue(or.CurrencyId, ppItem.CurrencyId, ppItem.UnitCost, countryProg.Id);
                orItem.EstimatedPrice = orItem.EstimatedUnitPrice * ppItem.Quantity;
                orItem.Quantity = ppItem.Quantity;
                orItem.ItemDescription = ppItem.ItemDescription;
                orItem.ItemId = ppItem.ItemId;
                orItem.OrderRequestId = model.OrderRequestId;                
                orderRequestService.AddOrderRequstItem(orItem, UserSession.CurrentSession.NewOR);
                if (UserSession.CurrentSession.NewOR != null)
                    UserSession.CurrentSession.NewOR = null;
                //mark the ppItem as added to OR
                ppItem.AddedToOR = true;
                ppItem.OrderRequestItemId = orItem.Id;
                ppService.SaveProcurementPlanItem(ppItem);
            }

            return ViewOrderRequestItems(model.OrderRequestId);
        }

        public ActionResult UpdateOrderRequest(Models.ORequest entity)
        {
            Model.OrderRequest or = orderRequestService.GetOrderRequestById(entity.EntityOrderRequest.Id);
            or.ProjectId = entity.ProjectId;
            or.CurrencyId = entity.CurrencyID;
            or.ProjectDonorId = entity.ProjectDonorId;
            or.RequestedDestinationId = entity.RequestDelivLocationID;
            or.FinalDestinationId = entity.FinalDelivLocationID;
            or.OrderDate = entity.IssueDate;
            or.DeliveryDate = entity.RequestDate;
            orderRequestService.EditOrderRequest(or);
            return ViewOrderRequestItems(or.Id);
        }

        public ActionResult DeleteOrderRequest(Guid id)
        {
            List<Model.OrderRequestItem> orItems = orderRequestService.GetOrderRequestItems(id);
            foreach (Model.OrderRequestItem orItem in orItems)
                orderRequestService.DeleteOrderRequstItem(orItem.Id);
            orderRequestService.DeleteOrderRequst(id);
            return ViewOrderRequests();
        }

        public ActionResult LoadRequestItem(Guid id)
        {
            return PopulateCreateItem(id);
        }

        private ActionResult PopulateCreateItem(Guid id, string errormessage = "", Guid? selectedItem = null)
        {
            using (var db = new SCMSEntities())
            {

                Model.OrderRequest or = UserSession.CurrentSession.NewOR == null ? db.OrderRequests.FirstOrDefault(p => p.Id == id) : UserSession.CurrentSession.NewOR;
                List<BudgetLineView> blList = orderRequestService.GetProjectBugdetLines((Guid)or.ProjectDonorId);
                ChildtRequest model = new ChildtRequest()
                {
                    EntityOrderRequestItem = new OrderRequestItem(),
                    BudgetLines = new SelectList(blList, "Id", "Description"),
                    Items = new SelectList(orderRequestService.GetItems(countryProg.Id), "Id", "Name")
                };
                if (selectedItem.HasValue)
                {
                    model.ItemID = selectedItem.Value;
                }
                ViewBag.Action = "Add";
                ViewBag.OrderRequestID = id;
                return View("LoadRequestItem", model);
            }
        }

        public ActionResult AddItemInEditMode(Guid id)
        {
            using (var db = new SCMSEntities())
            {
                Model.OrderRequest or = orderRequestService.GetOrderRequestById(id);
                List<BudgetLineView> blList = orderRequestService.GetProjectBugdetLines((Guid)or.ProjectDonorId);
                ChildtRequest model = new ChildtRequest()
                {
                    EntityOrderRequestItem = new OrderRequestItem(),
                    BudgetLines = new SelectList(blList, "Id", "Description"),
                    Items = new SelectList(orderRequestService.GetItems(countryProg.Id), "Id", "Name")
                };
                ViewBag.Action = "Add";
                ViewBag.OrderRequestID = id;
                return View("AddItemInEditMode", model);
            }
        }

        public ActionResult EditItem(Guid id)
        {
            using (var db = new SCMSEntities())
            {
                Model.OrderRequestItem oritem = db.OrderRequestItems.FirstOrDefault(p => p.Id == id);
                List<BudgetLineView> blList = orderRequestService.GetProjectBugdetLines((Guid)oritem.ProjectBudget.BudgetCategory.ProjectDonorId);
                var model = new ChildtRequest()
                {
                    EntityOrderRequestItem = oritem,
                    BudgetLines = new SelectList(blList, "Id", "Description", oritem.ProjectBudget.Id),
                    Items = new SelectList(orderRequestService.GetItems(countryProg.Id), "Id", "Name"),
                    BudgetLineID = oritem.BudgetLineId,
                    ItemID = oritem.ItemId
                };
                ViewBag.Action = "Update";
                ViewBag.OrderRequestID = id;
                return View("LoadRequestItem", model);
            }
        }

        public ActionResult EditItemInEditMode(Guid id)
        {
            using (var db = new SCMSEntities())
            {
                Model.OrderRequestItem oritem = db.OrderRequestItems.FirstOrDefault(p => p.Id == id);
                List<BudgetLineView> blList = orderRequestService.GetProjectBugdetLines((Guid)oritem.ProjectBudget.BudgetCategory.ProjectDonorId);
                var model = new ChildtRequest()
                {
                    EntityOrderRequestItem = oritem,
                    BudgetLines = new SelectList(blList, "Id", "Description", oritem.ProjectBudget.Id),
                    Items = new SelectList(orderRequestService.GetItems(countryProg.Id), "Id", "Name"),
                    BudgetLineID = oritem.BudgetLineId,
                    ItemID = oritem.ItemId
                };
                ViewBag.Action = "Update";
                ViewBag.OrderRequestID = id;
                return View("AddItemInEditMode", model);
            }
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult LoadRequestItem(Guid id, Models.ChildtRequest entity)
        {
            if (this.IsItemAdded(entity.EntityOrderRequestItem.ItemId, id))
            {
                if (entity.EntityOrderRequestItem.OrderRequestId.Equals(Guid.Empty))
                    entity.EntityOrderRequestItem.OrderRequestId = id;
                else
                    id = entity.EntityOrderRequestItem.OrderRequestId;
                entity.EntityOrderRequestItem.BudgetLineId = entity.BudgetLineID;
                entity.EntityOrderRequestItem.ItemDescription = entity.Description;
                if (orderRequestService.AddOrderRequstItem(entity.EntityOrderRequestItem, UserSession.CurrentSession.NewOR))
                {
                    ViewBag.OrderRequestID = entity.EntityOrderRequestItem.OrderRequestId;
                    ViewBag.Response = 1;
                    ViewBag.msg = "OR Item saved successfully";
                    UserSession.CurrentSession.NewOR = null;
                }
                ModelState.Clear();
            }
            else { ViewBag.Response = 0; ViewBag.msg = "This item is already added"; }
            Models.LoadORDetailsz modelORDetails;
            List<OrderRequestItem> TBList = orderRequestService.GetOrderRequestItems(id);
            ORItemsz = new List<LoadORDetailsz>();
            foreach (OrderRequestItem bc in TBList)
            {
                modelORDetails = new LoadORDetailsz();
                modelORDetails.EntityOrderRequestItem = bc;
                modelORDetails.ProjectNo = orderRequestService.GetProjectDonorDetails((Guid)bc.OrderRequest.ProjectDonorId).ProjectNumber;
                modelORDetails.BudgetLine = orderRequestService.GetProjectBudgetDetails((Guid)bc.BudgetLineId).LineNumber;
                Model.UnitOfMeasure u = bc.Item.UnitOfMeasure;
                ORItemsz.Add(modelORDetails);
            }
            ViewBag.OrderRequestID = id;
            return View("OrderRequestItemsList", ORItemsz);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult SaveRequestItem(Guid id, Models.ChildtRequest entity)
        {
            if (this.IsItemAdded(entity.EntityOrderRequestItem.ItemId, id))
            {
                if (entity.EntityOrderRequestItem.OrderRequestId.Equals(Guid.Empty))
                    entity.EntityOrderRequestItem.OrderRequestId = id;
                else
                    id = entity.EntityOrderRequestItem.OrderRequestId;
                entity.EntityOrderRequestItem.BudgetLineId = entity.BudgetLineID;
                entity.EntityOrderRequestItem.ItemDescription = entity.Description;
                if (orderRequestService.AddOrderRequstItem(entity.EntityOrderRequestItem, UserSession.CurrentSession.NewOR))
                {
                    ViewBag.OrderRequestID = entity.EntityOrderRequestItem.OrderRequestId;
                    ViewBag.Response = 1;
                    ViewBag.msg = "OR Item saved successfully";
                }
                ModelState.Clear();
            }
            else { ViewBag.Response = 0; ViewBag.msg = "This item is already added"; }
            return ViewOrderRequestItems(id);
        }

        private bool IsItemAdded(Guid itemId, Guid orId)
        {
            using (var db = new SCMSEntities())
            {
                int vv = db.OrderRequestItems.Where(p => p.ItemId == itemId && p.OrderRequestId == orId).Count();
                return vv == 0 ? true : false;
            }

        }

        public ActionResult RemoveItem(Guid id)
        {
            OrderRequestItem orItem = orderRequestService.GetOrderRequestItemById(id);
            orderRequestService.DeleteOrderRequstItem(orItem.Id);
            ViewBag.Response = 1;
            ViewBag.msg = "OR Item deleted successfully";
            Models.LoadORDetailsz modelORDetails;
            List<OrderRequestItem> TBList = orderRequestService.GetOrderRequestItems(orItem.OrderRequestId);
            ORItemsz = new List<LoadORDetailsz>();
            foreach (OrderRequestItem bc in TBList)
            {
                modelORDetails = new LoadORDetailsz();
                modelORDetails.EntityOrderRequestItem = bc;
                modelORDetails.ProjectNo = orderRequestService.GetProjectDonorDetails((Guid)bc.OrderRequest.ProjectDonorId).ProjectNumber;
                modelORDetails.BudgetLine = orderRequestService.GetProjectBudgetDetails((Guid)bc.BudgetLineId).LineNumber;
                Model.UnitOfMeasure u = bc.Item.UnitOfMeasure;
                ORItemsz.Add(modelORDetails);
            }
            ViewBag.OrderRequestID = orItem.OrderRequestId;
            return View("OrderRequestItemsList", ORItemsz);
        }

        public ActionResult RemoveItemInEditMode(Guid id)
        {
            OrderRequestItem orItem = orderRequestService.GetOrderRequestItemById(id);
            orderRequestService.DeleteOrderRequstItem(orItem.Id);
            ViewBag.Response = 1;
            ViewBag.msg = "OR Item deleted successfully";
            ModelState.Clear();
            return ViewOrderRequestItems(orItem.OrderRequestId);
        }

        public ActionResult GetDonorName(Guid id)
        {
            StringBuilder blineOption = new StringBuilder();
            using (var dbcontenxt = new SCMSEntities())
            {
                Model.ProjectDonor pd = dbcontenxt.ProjectDonors.SingleOrDefault(p => p.Id == id);
                blineOption.Append("<label for=\"EntityOrderRequest_ProjectDonor_Donor_Name\">" + pd.Donor.Name + "</label>");
            }
            ViewBag.Html = blineOption.ToString();
            return View("SelectIndexChangeResponse");
        }

        public ActionResult SubmitOR(Guid Id)
        {
            Model.OrderRequest or = orderRequestService.GetOrderRequestById(Id);
            or.IsRejected = false;
            or.IsAuthorized = false;
            or.IsReviewed = false;
            or.IsSubmitted = true;
            or.PreparedBy = currentStaff.Id;
            or.PreparedOn = DateTime.Now;
            or.RefNumber = orderRequestService.GenerateUniquNumber(countryProg);
            orderRequestService.EditOrderRequest(or);
            //Send notification
            notificationService.SendToAppropriateApprover(NotificationHelper.orCode, NotificationHelper.approvalCode, or.Id);
            return ViewOrderRequests();
        }

        public ActionResult ViewOrderRequests()
        {
            UI.Models.ViewOR OR;
            List<UI.Models.ViewOR> ORList = new List<ViewOR>();
            List<Model.OrderRequest> ORRqst = orderRequestService.GetOrderRequests(countryProg.Id);
            using (var db = new SCMSEntities())
            {
                foreach (Model.OrderRequest item in ORRqst)
                {
                    OR = new ViewOR();
                    OR.EntityOR = item;
                    OR.PreparedBy = db.Staffs.SingleOrDefault(p => p.Id == item.PreparedBy);
                    Person ps = OR.PreparedBy.Person; Designation d = OR.PreparedBy.Designation;
                    OR.IssueDate = (DateTime)item.PreparedOn;
                    OR.RequestDate = (DateTime)item.OrderDate;
                    var productQuery = from b in db.OrderRequestItems
                                       where b.OrderRequestId == item.Id
                                       select b;
                    OR.FirstItem = productQuery.Count() != 0 ? productQuery.First().Item.Name : "";
                    OR.ProjNo = productQuery.Count() != 0 ? productQuery.First().ProjectBudget.BudgetCategory.ProjectDonor.ProjectNumber : "";
                    OR.ProjName = productQuery.Count() != 0 ? productQuery.First().ProjectBudget.BudgetCategory.ProjectDonor.Project.Name : "";
                    OR.Donor = item.ProjectDonor.Donor.ShortName;
                    ORList.Add(OR);
                }
                return View("ViewOrderRequests", ORList);
            }
        }

        public ActionResult ViewOrderRequestItems(Guid id)
        {

            ViewOR OR = Models.ORExtension.PrepareOR(orderRequestService, id, currentStaff.Id);
            //Manage approval link
            string actionType = null;
            if (OR.EntityOR.IsReviewed == true && OR.EntityOR.IsAuthorized == false)
                actionType = NotificationHelper.authorizationCode;
            else if (OR.EntityOR.IsApproved && OR.EntityOR.IsReviewed == false)
                actionType = NotificationHelper.reviewCode;
            else if (OR.EntityOR.IsSubmitted && !OR.EntityOR.IsApproved)
                actionType = NotificationHelper.approvalCode;
            if (actionType != null)
                OR.CanApprove = notificationService.CanApprove(currentUser, NotificationHelper.orCode, actionType, OR.EntityOR.Id);
            else
                OR.CanApprove = false;

            using (var db = new SCMSEntities())
            {
                Model.OrderRequest ORRqst = db.OrderRequests.SingleOrDefault(p => p.Id == id);
                Currency mbCurr = db.Currencies.SingleOrDefault(c => c.Id == ORRqst.MBCurrencyId);
                if (mbCurr != null)
                    ViewBag.MBCurrency = mbCurr.ShortName;
                return View("ViewOrderRequestItems", OR);
            }
        }

        public ActionResult GetBudgetLines(Guid id)
        {
            StringBuilder blineOption = new StringBuilder();
            blineOption.Append("<select class=\"dpl\" data-val=\"true\" data-val-required=\"The BudgetLineID field is required.\" id=\"BudgetLineID\" name=\"BudgetLineID\" onchange = \"javascript:checkBalance()\"><option value=\"\">---Please Select---</option>");
            List<Model.BudgetLineView> BLines = orderRequestService.GetProjectBugdetLines(id);
            foreach (BudgetLineView item in BLines)
                blineOption.Append("<option value=\"" + item.Id + "\">" + item.Description + "</option>");
            blineOption.Append("</select>");
            blineOption.Append("<span class=\"field-validation-valid\" data-valmsg-for=\"BudgetLineID\" data-valmsg-replace=\"true\"></span>");
            ViewBag.Html = blineOption.ToString();
            return View("SelectIndexChangeResponse");
        }

        /// <summary>
        /// Same as the above but for OR Items in a loop
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult GetBudgetLineForORItems(Guid id)
        {
            //# is a placeholder that will be replaced on the other side
            StringBuilder blinOption = new StringBuilder();
            blinOption.Append("<select class=\"smallControl\" id=\"ORItems_#__BudgetLineID\" name=\"ORItems[#].BudgetLineID\" onchange = \"javascript:checkBalance4Review(this)\">");
            List<Model.BudgetLineView> BLines = orderRequestService.GetProjectBugdetLines(id);
            foreach (BudgetLineView item in BLines)
                blinOption.Append("<option value=\"" + item.Id + "\">" + item.Description + "</option>");
            blinOption.Append("</select>");
            //blinOption.Append("<span class=\"field-validation-valid\" data-valmsg-for=\"EntityOrderRequestItem.ProjectDonorId\" data-valmsg-replace=\"true\"></span>");
            ViewBag.Html = blinOption.ToString();
            return View("SelectIndexChangeResponse");
        }

        /// <summary>
        /// Same as the above but for PO Items in a loop
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult GetBudgetLineForPOItems(Guid id)
        {
            //# is a placeholder that will be replaced on the other side
            StringBuilder blinOption = new StringBuilder();
            blinOption.Append("<select class=\"smallControl\" id=\"POItems_#__BudgetLineID\" name=\"POItems[#].BudgetLineID\" onchange = \"javascript:checkBalance4Review(this)\">");
            List<Model.BudgetLineView> BLines = orderRequestService.GetProjectBugdetLines(id);
            foreach (BudgetLineView item in BLines)
                blinOption.Append("<option value=\"" + item.Id + "\">" + item.Description + "</option>");
            blinOption.Append("</select>");
            ViewBag.Html = blinOption.ToString();
            return View("SelectIndexChangeResponse");
        }

        /// <summary>
        /// Same as the above but for RFP Items in a loop
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult GetBudgetLineForRFPItems(Guid id)
        {
            //# is a placeholder that will be replaced on the other side
            StringBuilder blinOption = new StringBuilder();
            blinOption.Append("<select id=\"paymentDetails_#__BudgetLineId\" name=\"paymentDetails[#].BudgetLineId\" onchange = \"javascript:checkBalance4Review(this)\">");
            List<Model.BudgetLineView> BLines = orderRequestService.GetProjectBugdetLines(id);
            foreach (BudgetLineView item in BLines)
                blinOption.Append("<option value=\"" + item.Id + "\">" + item.Description + "</option>");
            blinOption.Append("</select>");
            ViewBag.Html = blinOption.ToString();
            return View("SelectIndexChangeResponse");
        }

        /// <summary>
        /// Same as the above but for RFA Items in a loop
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult GetBudgetLineForRFAItems(Guid id)
        {
            //# is a placeholder that will be replaced on the other side
            StringBuilder blinOption = new StringBuilder();
            blinOption.Append("<select id=\"PaymentDetails_#__BudgetLineID\" name=\"PaymentDetails[#].BudgetLineID\" onchange = \"javascript:checkBalance4Review(this)\">");
            List<Model.BudgetLineView> BLines = orderRequestService.GetProjectBugdetLines(id);
            foreach (BudgetLineView item in BLines)
                blinOption.Append("<option value=\"" + item.Id + "\">" + item.Description + "</option>");
            blinOption.Append("</select>");
            ViewBag.Html = blinOption.ToString();
            return View("SelectIndexChangeResponse");
        }

        /// <summary>
        /// Same as the above but for ECF Items in a loop
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult GetBudgetLineForECFItems(Guid id)
        {
            //# is a placeholder that will be replaced on the other side
            StringBuilder blineOption = new StringBuilder();
            blineOption.Append("<select id=\"SalaryPaymentItems_#__BudgetLineId\" name=\"SalaryPaymentItems[#].BudgetLineId\" onchange = \"javascript:checkBalance4Review(this)\">");
            List<Model.BudgetLineView> BLines = orderRequestService.GetProjectBugdetLines(id);
            foreach (BudgetLineView item in BLines)
                blineOption.Append("<option value=\"" + item.Id + "\">" + item.Description + "</option>");
            blineOption.Append("</select>");
            blineOption.Append("<span class=\"field-validation-valid\" data-valmsg-for=\"SalaryPaymentItems[#].BudgetLineId\" data-valmsg-replace=\"true\"></span>");
            ViewBag.Html = blineOption.ToString();
            return View("SelectIndexChangeResponse");
        }

        /// <summary>
        /// Same as the above but for SPM Items in a loop
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult GetBudgetLineForSPMItems(Guid id)
        {
            //# is a placeholder that will be replaced on the other side
            StringBuilder blineOption = new StringBuilder();
            blineOption.Append("<select id=\"ExpenseClaimItems_#__BudgetLineId\" name=\"ExpenseClaimItems[#].BudgetLineId\" onchange = \"javascript:checkBalance4Review(this)\">");
            List<Model.BudgetLineView> BLines = orderRequestService.GetProjectBugdetLines(id);
            foreach (BudgetLineView item in BLines)
                blineOption.Append("<option value=\"" + item.Id + "\">" + item.Description + "</option>");
            blineOption.Append("</select>");
            blineOption.Append("<span class=\"field-validation-valid\" data-valmsg-for=\"ExpenseClaimItems[#].BudgetLineId\" data-valmsg-replace=\"true\"></span>");
            ViewBag.Html = blineOption.ToString();
            return View("SelectIndexChangeResponse");
        }

        /// <summary>
        /// Same as the above but for PO Items in a loop in create purchase order
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult GetBudgetLineForCreatePOItems(Guid id)
        {
            //# is a placeholder that will be replaced on the other side
            StringBuilder blinOption = new StringBuilder();
            blinOption.Append("<select class=\"poTextBox\" id=\"ORItems_#__EntityORItem_BudgetLineId\" name=\"ORItems[#].BudgetLineId\">");
            List<Model.BudgetLineView> BLines = orderRequestService.GetProjectBugdetLines(id);
            foreach (BudgetLineView item in BLines)
                blinOption.Append("<option value=\"" + item.Id + "\">" + item.Description + "</option>");
            blinOption.Append("</select>");
            ViewBag.Html = blinOption.ToString();
            return View("SelectIndexChangeResponse");
        }

        /// <summary>
        /// Same as the above but for create PO for TA
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult GetBudgetLineForCreatePOTAItems(Guid id)
        {
            //# is a placeholder that will be replaced on the other side
            StringBuilder blinOption = new StringBuilder();
            blinOption.Append("<select class=\"poTextBox\" id=\"ORTenderItems_#__TBQuoteEntity_OrderRequestItem_BudgetLineId\" name=\"ORTenderItems[#].BudgetLineId\">");
            List<Model.BudgetLineView> BLines = orderRequestService.GetProjectBugdetLines(id);
            foreach (BudgetLineView item in BLines)
                blinOption.Append("<option value=\"" + item.Id + "\">" + item.Description + "</option>");
            blinOption.Append("</select>");
            ViewBag.Html = blinOption.ToString();
            return View("SelectIndexChangeResponse");
        }

        public ActionResult Search()
        {
            var model = new Search()
            {
                EntityOrderRequest = new Model.OrderRequest()
            };
            return View(model);
        }

        [HttpPost]
        public ActionResult Search(Search search)
        {
            UI.Models.ViewOR OR;
            List<UI.Models.ViewOR> ORList = new List<ViewOR>();
            List<Model.OrderRequest> ORRqst = orderRequestService.Search(search.EntityOrderRequest);
            using (var db = new SCMSEntities())
            {
                foreach (Model.OrderRequest item in ORRqst)
                {
                    OR = new ViewOR();
                    OR.EntityOR = item;

                    OR.PreparedBy = db.Staffs.SingleOrDefault(p => p.Id == item.PreparedBy);
                    Person ps = OR.PreparedBy.Person; Designation d = OR.PreparedBy.Designation;
                    OR.IssueDate = item.PreparedOn.Value;
                    OR.RequestDate = item.OrderDate.Value;
                    OR.Donor = db.ProjectDonors.SingleOrDefault(p => p.Id == item.ProjectDonorId).Donor.Name;
                    var productQuery = from b in db.OrderRequestItems
                                       where b.OrderRequestId == item.Id
                                       select b;
                    OR.FirstItem = productQuery.Count() != 0 ? productQuery.First().Item.Name : "";
                    OR.ProjNo = productQuery.Count() != 0 ? productQuery.First().ProjectBudget.BudgetCategory.ProjectDonor.ProjectNumber : "";
                    OR.ProjName = productQuery.Count() != 0 ? productQuery.First().ProjectBudget.BudgetCategory.ProjectDonor.Project.Name : "";
                    ORList.Add(OR);
                }
                return View("ViewOrderRequests", ORList);
            }

        }

        [HttpGet]
        public ActionResult AddNewLocation4OR(bool final, Guid? otherDDSelectedId)
        {
            ULocation model = new ULocation();
            model.CountrySelect = new SelectList(locationService.CountryObj.GetCountries(), "Id", "Name");
            model.CountryId = countryProg.CountryId;
            model.IsFinal = final;
            ViewBag.OtherDDSelectedId = otherDDSelectedId;
            return View("AddNewLocation4OR", model);
        }

        [HttpPost]
        public ActionResult AddNewLocation4OR(ULocation model, bool final, Guid? otherDDSelectedId)
        {
            Location location = locationService.GetLocationByName(model.Name, countryProg.Id);
            if (location == null)
            {
                location = new Location();
                location.Name = model.Name;
                location.Description = model.Description;
                location.CountryId = model.CountryId;
                location.CountryProgrammeId = countryProg.Id;
                //location.IsApproved = false;
                locationService.AddLocation(location);
            }
            return RepopulateLocationLists(location.Id, final, otherDDSelectedId);
        }

        private ActionResult RepopulateLocationLists(Guid selectedLocationId, bool final, Guid? otherDDSelectedId)
        {
            StringBuilder locationDropDown = new StringBuilder();
            StringBuilder finalLocationDD = new StringBuilder();
            string selected = "";
            locationDropDown.Append("<select data-val=\"true\" data-val-required=\"Required Field.\" id=\"RequestDelivLocationID\" name=\"RequestDelivLocationID\"><option value=\"\">--Please Select--</option>");
            List<Model.Location> locations = orderRequestService.GetLocations(countryProg.Id);
            foreach (Location location in locations)
            {
                if (!final && location.Id.Equals(selectedLocationId))
                    selected = "selected";
                else if (final && otherDDSelectedId.HasValue && location.Id.Equals(otherDDSelectedId.Value))
                    selected = "selected";
                else
                    selected = "";
                locationDropDown.Append("<option value=\"" + location.Id + "\" " + selected + ">" + location.Name + "</option>");
            }
            locationDropDown.Append("</select>");
            locationDropDown.Append("<span class=\"field-validation-valid\" data-valmsg-for=\"RequestDelivLocationID\" data-valmsg-replace=\"true\"></span>");

            //final location DD
            selected = "";
            finalLocationDD.Append("<select data-val=\"true\" data-val-required=\"Required Field.\" id=\"FinalDelivLocationID\" name=\"FinalDelivLocationID\"><option value=\"\">--Please Select--</option>");
            
            foreach (Location location in locations)
            {
                if (final && location.Id.Equals(selectedLocationId))
                    selected = "selected";
                else if (!final && otherDDSelectedId.HasValue && location.Id.Equals(otherDDSelectedId.Value))
                    selected = "selected";
                else
                    selected = "";
                finalLocationDD.Append("<option value=\"" + location.Id + "\" " + selected + ">" + location.Name + "</option>");
            }
            finalLocationDD.Append("</select>");
            finalLocationDD.Append("<span class=\"field-validation-valid\" data-valmsg-for=\"FinalDelivLocationID\" data-valmsg-replace=\"true\"></span>");
            return Content(locationDropDown.ToString() + "###" + finalLocationDD.ToString());
        }

        [HttpGet]
        public ActionResult AddNewItem(Guid id)
        {
            //maintain session OR variable if not null
            if (UserSession.CurrentSession.NewOR != null)
            {
                var or = UserSession.CurrentSession.NewOR;
            }
            UItem model = new UItem
            {
                ItemCatSelect = new SelectList(itemService.ItemCatObj.GetItemCategories(), "Id", "CategoryName"),
                ItemClassSelect = new SelectList(itemService.ItemClassObj.GetItemClassifications(countryProg.Id), "Id", "Name"),
                ItemUnitsSelect = new SelectList(itemService.ItemClassObj.GetUnitOfMessures(countryProg.Id), "Id", "Code")
            };
            ViewBag.OrId = id;
            return View("AddNewItem4OR", model);
        }

        [HttpPost]
        public ActionResult AddNewItem(UItem model, Guid orId)
        {
            //maintain session OR variable if not null
            if (UserSession.CurrentSession.NewOR != null)
            {
                var or = UserSession.CurrentSession.NewOR;
            }
            Item item = itemService.GetItemByName(model.Name, countryProg.Id);
            if (item == null)
            {
                item = new Item();
                item.Name = model.Name;
                item.ItemCategoryId = model.ItemCategoryId;
                item.ItemClassificationId = model.ItemClassificationId;
                item.UnitOfMessureId = model.UnitId;
                item.CountryProgrammeId = countryProg.Id;
                item.IsApproved = false;
                itemService.AddItem(item);                
            }
            return PopulateCreateItem(orId, "", item.Id);
        }
    }
}
